﻿using MQTTnet;
using MQTTnet.Client;
using System;
using System.Text;
using System.Threading.Tasks;

namespace Universal.Protocal.MQTT
{
    public class MqttClientService
    {
        private IMqttClient mqttClient = null;
        private bool isConnected = false;
        public bool IsConnected
        {
            get => isConnected;
            set
            {
                isConnected = value;
                if (isConnected)
                {
                    Log("Client 已连接");
                }
                else
                {
                    Log("Client 连接中断");
                }
            }
        }
        public virtual async void StartClient(string hostIP,int hostPort,string id,string userName,string userPassword)
        {
            if (mqttClient == null)
            {
                var factory = new MqttFactory();
                mqttClient = factory.CreateMqttClient();

                mqttClient.ApplicationMessageReceivedAsync += ApplicationMessageReceived;
                mqttClient.ConnectedAsync += Connected;
                mqttClient.DisconnectedAsync += Disconnected;
            }
            try
            {
                var options = new MqttClientOptionsBuilder()
                    .WithClientId(id)
                    .WithTcpServer(hostIP, hostPort)
                    .WithCredentials(userName, userPassword)
                    .WithCleanSession()
                    .Build();
                await mqttClient.ConnectAsync(options);
            }
            catch (Exception ex)
            {
            }
        }

        public virtual void SendMsg(string topic,string msg)
        {
            if(mqttClient != null && IsConnected)
            {
                mqttClient.PublishAsync(new MqttApplicationMessage()
                {
                    Topic = topic,
                    Retain = false,
                    PayloadSegment = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msg))
                });
            }
        }

        private void Log(string msg)
        {
            Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss:fff")} : {msg}");
        }

        private async Task Disconnected(MqttClientDisconnectedEventArgs args)
        {
            IsConnected = false;
            await Task.Run(() =>
            {

            });
        }

        /// <summary>
        /// 连接后执行订阅
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        private async Task Connected(MqttClientConnectedEventArgs args)
        {
            IsConnected = true;
            await Task.Run(() =>
            {
                Log("Client 已连接");
            });
        }

        private async Task ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs args)
        {
            await Task.Run(() =>
            {
                var topic = args.ApplicationMessage.Topic;
                var msg = Encoding.UTF8.GetString(args.ApplicationMessage.PayloadSegment.Array);              
                Log($"topic: {topic} msg: {msg}");
            });
        }
    }
}
